/*
 * TextPaneDelegate.cpp  0.4.0 / Dec 04, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "TextPaneDelegate.h"

#include "QCursorAdapter.h"
#include "TextDocumentDelegate.h"

// TextPaneDelegate :: Protected Constructor. ----------------------------------

/*!
 * \brief Constructs new TextPaneDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj the TextPane java object
 */
TextPaneDelegate::TextPaneDelegate(JNIEnv *env, jobject obj)
  : TextComponentDelegate(env, obj, new QTextPane(this))
{
  // empty constructor body
}

// TextPaneDelegate :: Native Calls. -------------------------------------------

/*!
 * \brief Sets text wrapping mode.
 *
 * \param env the JNIEnv pointer
 * \param textWrap \c true if wrapping text
 */
void TextPaneDelegate::setWrapText(JNIEnv *env, jboolean textWrap)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setWrapText, SWING_ENV_ARG, JBOOLEAN_ARG(textWrap))
  if (textWrap) {
    qTextPane()->setLineWrapMode(QTextEdit::WidgetWidth);
  } else {
    qTextPane()->setLineWrapMode(QTextEdit::NoWrap);
  }
}

/*!
 * \brief Paints default component view.
 *
 * \param env the JNIEnv pointer
 * \param graphicsPointer the SwingGraphics pointer
 */
void TextPaneDelegate::paintComponentView(JNIEnv *env, jlong graphicsPointer)
{
  Q_ASSERT(env);
  SWING_REENTRANT(paintComponentView, SWING_ENV_ARG, JLONG_ARG(graphicsPointer))
  qTextPane()->paintView(graphicsPointer);
}

// TextPaneDelegate :: Static Native Calls. ------------------------------------

/*!
 * \brief Initializes TextPaneDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param cls the TextArea java class
 *
 * \exception FatalError if failed
 */
void TextPaneDelegate::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT(!sm_paintViewMID);
  if (!INIT_UMID(paintView, cls, "(JIIII)V")) {
    FATAL_LOGGED_ERROR("TextPaneDelegate initialization failed");
  }
}

/*!
 * \brief Returns new instance of the delegate object
 *
 * \param env the JNIEnv pointer
 * \param obj the Swing object
 * 
 * \return new instance of the delegate object
 */
jlong TextPaneDelegate::newInstance(JNIEnv *env, jobject obj)
{
  if (JNISwingWrapper::isSwingThread(env)) {
    return reinterpret_cast<jlong>(new TextPaneDelegate(env, obj));
  }
  return SwingUtilitiesDelegate::invokeLongAndWait(env, obj, createMID());
}

// TextPaneDelegate :: Native Callbacks. ---------------------------------------

/*!
 * \brief Paint component view
 *
 * \param graphicsPointer the graphics pointer
 * \param x the x-coordinate of the view
 * \param y the y-coordinate of the view
 * \param width width the width of the view
 * \param height height the height of the view
 */
void TextPaneDelegate::paintView(jlong graphicsPointer, jint x, jint y,
                                 jint width, jint height)
{
  jniObject()->callVoidMethod(sm_paintViewMID, graphicsPointer, x, y, width,
                              height);
}

// TextPaneDelegate :: Overridden Member Functions. ----------------------------

/*!
 * \brief Sets document.
 *
 * \param env the JNIEnv pointer
 * \param document the new document 
 */
void TextPaneDelegate::setDocument(JNIEnv *env, jobject document)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setDocument, SWING_ENV_ARG, JOBJECT_ARG(document))
  qTextPane()->setDocument(TextDocumentDelegate::toQDocument(env, document));
}

/*!
 * \brief Sets whether or not text pane is editable.
 *
 * \param env the JNIEnv pointer
 * \param editable \c true if editable
 */
void TextPaneDelegate::setEditable(JNIEnv *env, jboolean editable)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setEditable, SWING_ENV_ARG, JBOOLEAN_ARG(editable))
  qTextPane()->setReadOnly(!editable);
}

/*!
 * \brief Inserts text.
 *
 * \param env the JNIEnv pointer
 * \param text text the text to be inserted
 */
void TextPaneDelegate::insertText(JNIEnv *env, jstring text)
{
  Q_ASSERT(env);
  Q_ASSERT(text);
  SWING_REENTRANT(insertText, SWING_ENV_ARG, JSTRING_ARG(text))
  qTextPane()->textCursor().insertText(QStringAdapter(env, text));
}

/*!
 * \brief Cuts selected text.
 *
 * \param env the JNIEnv pointer
 */
void TextPaneDelegate::cut(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(cut, SWING_ENV_ARG)
  qTextPane()->cut();
}

/*!
 * \brief 
 *
 * \param env the JNIEnv pointer
 */
void TextPaneDelegate::copy(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(copy, SWING_ENV_ARG)
  qTextPane()->copy();
}

/*!
 * \brief Paste text form the system clipboard.
 *
 * \param env the JNIEnv pointer
 */
void TextPaneDelegate::paste(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(paste, SWING_ENV_ARG)
  qTextPane()->paste();
}

/*!
 * \brief Clears selected text.
 *
 * \param env the JNIEnv pointer
 */
void TextPaneDelegate::clear(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(clear, SWING_ENV_ARG)
  qTextPane()->textCursor().removeSelectedText();
}

/*!
 * \brief Selects all text.
 *
 * \param env the JNIEnv pointer
 */
void TextPaneDelegate::selectAll(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(selectAll, SWING_ENV_ARG)
  qTextPane()->selectAll();
}

/*!
 * \inheritDoc
 */
jobject TextPaneDelegate::getBackground(JNIEnv *env, jclass colorClass)
{
  return QColorAdapter::toJColor(env, colorClass,
                        qTextPane()->viewport()->palette().color(
                                    qTextPane()->viewport()->backgroundRole()));
}

/*!
 * \inheritDoc
 */
void TextPaneDelegate::setBackground(JNIEnv *env, jint argb)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setBackground, SWING_ENV_ARG, JINT_ARG(argb))
  QColorAdapter color(argb);
  QPalette palette(qTextPane()->viewport()->palette());
  if (color.isValid()) {
    palette.setColor(qTextPane()->viewport()->backgroundRole(), color);
  } else {
    palette.setColor(qTextPane()->viewport()->backgroundRole(),
                     QApplication::palette().color(
                                   qTextPane()->viewport()->backgroundRole()));
  }
  qTextPane()->viewport()->setPalette(palette);
}

/*!
 * \inheritDoc
 */
void TextPaneDelegate::setNullBackground(JNIEnv *env)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setNullBackground, SWING_ENV_ARG)
  QPalette palette(qTextPane()->viewport()->palette());
  palette.setColor(qTextPane()->viewport()->backgroundRole(),
                   QApplication::palette().color(
                                 qTextPane()->viewport()->backgroundRole()));
  qTextPane()->viewport()->setPalette(palette);
}

/*!
 * \inheritDoc
 */
jint TextPaneDelegate::getCursor(JNIEnv *env)
{
  Q_UNUSED(env);
  return QCursorAdapter::cursorType(qTextPane()->viewport()->cursor());
}

/*!
 * \inheritDoc
 */
void TextPaneDelegate::setCursor(JNIEnv *env, jint type)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setCursor, SWING_ENV_ARG, JINT_ARG(type))
  if (type < 0) {
    qTextPane()->viewport()->unsetCursor();
  } else {
    qTextPane()->viewport()->setCursor(QCursorAdapter(type));
  }
}

/*!
 * \inheritDoc.
 */
void TextPaneDelegate::filterEnabledEvents()
{
  ComponentDelegate::filterEnabledEvents();
  qTextPane()->setPaintView(eventEnabled(SWING_EVENT(PAINT_VIEW_EVENT_MASK)));
}

// TextPaneDelegate :: Private Static Data Members. ----------------------------

jmethodID TextPaneDelegate::sm_paintViewMID = 0;
